#include "gameroom.h"
#include "gameselect.h"
#include <QPainter>
#include <QIcon>
#include <QRectF>
#include <QTimer>
#include <QPushButton>
#include <QSound>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>

GameRoom::GameRoom(QWidget *parent) : QWidget(parent)
{
    // 设置游戏房间大小、图标、名字
    this->setFixedSize(1080,720);
    this->setWindowIcon(QIcon(":Resource/icon.png"));
    this->setWindowTitle("游戏房间");

    // 初始化贪吃蛇
    snakeList.push_back(QRectF(this->width() * 0.5,this->height() * 0.5,kSnakeNodeWight,kSnakeNodeHeight));

    moveUP();
    moveUP();

    creatFood();

    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,[=](){
        int count = 1;
        if(snakeList.front().intersects(foodRect))
        {
            creatFood();
            count++;
            QSound::play(":Resource/eatfood.wav");
        }

        while(count--)
        {
            switch(moveDirect)
            {
            case SnakeDirect::UP:
                moveUP();
                break;
            case SnakeDirect::DOWN:
                moveDOWN();
                break;
            case SnakeDirect::LEFT:
                moveLEFT();
                break;
            case SnakeDirect::RIGHT:
                moveRIGHT();
                break;
            }
        }

        snakeList.pop_back();
        update();
    });

    // 开始游戏、暂停游戏
    QFont font("楷体",20);

    QPushButton* pushButton_start = new QPushButton(this);
    pushButton_start->move(890,460);
    pushButton_start->setGeometry(890,460,100,60);
    pushButton_start->setText("开始");
    pushButton_start->setFont(font);
    connect(pushButton_start,&QPushButton::clicked,[=](){
        isGameStart = true;
        timer->start(moveTimeout);
        sound = new QSound(":Resource/Trepak.wav");
        sound->play();
        sound->setLoops(-1);
    });

    QPushButton* pushButton_stop = new QPushButton(this);
    pushButton_stop->move(890,540);
    pushButton_stop->setGeometry(890,540,100,60);
    pushButton_stop->setText("暂停");
    pushButton_stop->setFont(font);
    connect(pushButton_stop,&QPushButton::clicked,[=](){
        isGameStart = false;
        timer->stop();
        sound->stop();
    });

    // 设置方向键的位置、大小、图标和快捷键
    QPushButton* pushButton_up = new QPushButton(this);
    pushButton_up->move(900,220);
    pushButton_up->setGeometry(900,220,80,60);
    pushButton_up->setIcon(QIcon(":Resource/up1.png"));
    connect(pushButton_up,&QPushButton::clicked,[=](){
        if(moveDirect != SnakeDirect::DOWN)
            moveDirect = SnakeDirect::UP;
    });
    pushButton_up->setShortcut(QKeySequence(Qt::Key_W));

    QPushButton* pushButton_down = new QPushButton(this);
    pushButton_down->move(900,340);
    pushButton_down->setGeometry(900,340,80,60);
    pushButton_down->setIcon(QIcon(":Resource/down1.png"));
    connect(pushButton_down,&QPushButton::clicked,[=](){
        if(moveDirect != SnakeDirect::UP)
            moveDirect = SnakeDirect::DOWN;
    });
    pushButton_down->setShortcut(QKeySequence(Qt::Key_S));

    QPushButton* pushButton_left = new QPushButton(this);
    pushButton_left->move(820,280);
    pushButton_left->setGeometry(820,280,80,60);
    pushButton_left->setIcon(QIcon(":Resource/left1.png"));
    connect(pushButton_left,&QPushButton::clicked,[=](){
        if(moveDirect != SnakeDirect::RIGHT)
            moveDirect = SnakeDirect::LEFT;
    });
    pushButton_left->setShortcut(QKeySequence(Qt::Key_A));

    QPushButton* pushButton_right = new QPushButton(this);
    pushButton_right->move(980,280);
    pushButton_right->setGeometry(980,280,80,60);
    pushButton_right->setIcon(QIcon(":Resource/right1.png"));
    connect(pushButton_right,&QPushButton::clicked,[=](){
        if(moveDirect != SnakeDirect::LEFT)
            moveDirect = SnakeDirect::RIGHT;
    });
    pushButton_right->setShortcut(QKeySequence(Qt::Key_D));

    // 设置退出按钮
    QPushButton* pushButton_exit = new QPushButton(this);
    pushButton_exit->move(890,620);
    pushButton_exit->setGeometry(890,620,100,60);
    pushButton_exit->setText("退出");
    pushButton_exit->setFont(font);

    // 设置退出弹窗
    QMessageBox* messageBox = new QMessageBox(this);
    QPushButton* pushButton_yes = new QPushButton("确认");
    QPushButton* pushButton_no = new QPushButton("取消");
    messageBox->addButton(pushButton_yes,QMessageBox::AcceptRole);
    messageBox->addButton(pushButton_no,QMessageBox::RejectRole);
    messageBox->setWindowTitle("退出游戏");
    messageBox->setText("确认退出游戏吗？");
    connect(pushButton_exit,&QPushButton::clicked,[=](){
        messageBox->show();
        messageBox->exec();
        QSound::play(":Resource/clicked.wav");

        GameSelect* select = new GameSelect;
        if(messageBox->clickedButton() == pushButton_yes)
        {
            this->close();
            sound->stop();
            select->show();
        }
        else
        {
            messageBox->close();
        }
    });
}

void GameRoom::paintEvent(QPaintEvent *event)
{
    (void) *event;
    QPainter painter(this);
    QPixmap pix(":Resource/game_room.png");
    painter.drawPixmap(0,0,800,this->height(),pix);

    pix.load(":Resource/bg1.png");
    painter.drawPixmap(800,0,280,800,pix);

    // 绘制蛇
    if(moveDirect == SnakeDirect::UP)
    {
        pix.load(":Resource/up.png");
    }
    else if(moveDirect == SnakeDirect::DOWN)
    {
        pix.load(":Resource/down.png");
    }
    else if(moveDirect == SnakeDirect::LEFT)
    {
        pix.load(":Resource/left.png");
    }
    else
    {
        pix.load(":Resource/right.png");
    }

    // 绘制蛇头、身体和尾巴
    auto Head = snakeList.front();
    painter.drawPixmap(Head.x(),Head.y(),Head.width(),Head.height(),pix);

    pix.load(":Resource/Bd.png");
    for (int i = 0;i < snakeList.size() - 1;i++)
    {
        auto Body = snakeList.at(i);
        painter.drawPixmap(Body.x(),Body.y(),Body.width(),Body.height(),pix);
    };

    auto tail = snakeList.back();
    painter.drawPixmap(tail.x(),tail.y(),tail.width(),tail.height(),pix);

    // 绘制食物
    pix.load(":Resource/food.png");
    painter.drawPixmap(foodRect.x(),foodRect.y(),foodRect.width(),foodRect.height(),pix);

    // 绘制分数
    pix.load(":Resource/sorce_bg.png");
    painter.drawPixmap(890,50,120,60,pix);

    QPen pen;
    pen.setColor(Qt::black);
    painter.setPen(pen);
    QFont font("仿宋",24);
    painter.setFont(font);
    painter.drawText(955,95,QString("%1").arg(snakeList.size() - 3));

    // 往文件中写分数
    int score = snakeList.size() - 3;
    QFile file("D:/bite/C-program/project/Snake/gamedata.txt");
    if(file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QTextStream out(&file);
        int num = score;
        out << num;
        file.close();
    }

    // 绘制游戏失败
    if(checkFail())
    {
        pen.setColor(Qt::red);
        painter.setPen(pen);
        QFont font("仿宋",50);
        painter.setFont(font);
        painter.drawText(this->width() * 0.2,this->height() * 0.5,QString("游戏失败"));
        timer->stop();

        QSound::play(":Resource/gameover.wav");
        sound->stop();
    }
}

void GameRoom::moveUP()
{
    QPointF leftTop;
    QPointF rightBottom;

    // 蛇头
    auto snakeNode = snakeList.front();
    int headX = snakeNode.x();
    int headY = snakeNode.y();

    // 如果穿模
    if(headY < 20)
    {
        leftTop = QPointF(headX,this->height() - kSnakeNodeHeight);
    }
    else
    {
        leftTop = QPointF(headX,headY - kSnakeNodeHeight);
    }

    rightBottom = leftTop + QPointF(kSnakeNodeWight,kSnakeNodeHeight);

    snakeList.push_front(QRectF(leftTop,rightBottom));
}

void GameRoom::moveDOWN()
{
    QPointF leftTop;
    QPointF rightBottom;

    auto snakeNode = snakeList.front();
    int headX = snakeNode.x();
    int headY = snakeNode.y();

    if(headY > this->height())
    {
        leftTop = QPointF(headX,0);
    }
    else
    {
        leftTop = snakeNode.bottomLeft();
    }

    rightBottom = leftTop + QPointF(kSnakeNodeWight,kSnakeNodeHeight);

    snakeList.push_front(QRectF(leftTop,rightBottom));
}

void GameRoom::moveLEFT()
{
    QPointF leftTop;
    QPointF rightBottom;

    auto snakeNode = snakeList.front();
    int headX = snakeNode.x();
    int headY = snakeNode.y();

    if(headX < 0)
    {
        leftTop = QPointF(800 - kSnakeNodeWight,headY);
    }
    else
    {
        leftTop = QPointF(headX - kSnakeNodeWight,headY);
    }

    rightBottom = leftTop + QPointF(kSnakeNodeWight,kSnakeNodeHeight);
    snakeList.push_front(QRectF(leftTop,rightBottom));
}

void GameRoom::moveRIGHT()
{
    QPointF leftTop;
    QPointF rightBottom;

    auto snakeNode = snakeList.front();
    int headX = snakeNode.x();
    int headY = snakeNode.y();

    if(headX > 760)
    {
        leftTop = QPointF(0,headY);
    }
    else
    {
        leftTop = snakeNode.topRight();
    }

    rightBottom = leftTop + QPointF(kSnakeNodeWight,kSnakeNodeHeight);
    snakeList.push_front(QRectF(leftTop,rightBottom));
}

bool GameRoom::checkFail()
{
    for(int i = 0;i < snakeList.size();i++)
    {
        for(int j = i + 1;j < snakeList.size();j++)
        {
            if(snakeList.at(i) == snakeList.at(j))
            {
                return true;
            }
        }
    }
    return false;
}

void GameRoom::creatFood()
{
    foodRect = QRectF(qrand() % (800 / kSnakeNodeWight) * kSnakeNodeWight,
                      qrand() % (this->height() / kSnakeNodeHeight) * kSnakeNodeHeight,
                      kSnakeNodeWight,kSnakeNodeHeight);
}
